#include "StdAfx.h"
#include <Engine/Map.hpp>
#include <Engine/MapRenderer.hpp>
#include <Engine/UnitEntity.hpp>
#include "GameFramework.hpp"

namespace
{
	int vpWidth, vpHeight;
	void convertScreenMetrics(float X, float Y, float& ToX, float &Toy, Ogre::Camera &Camera)
	{
		// Actual width of Viewport - I have set my camera(mCam) as viewPort
		float scrx = X / vpWidth; 
		float scry = Y / vpHeight;
		Ogre::Ray ray = Camera.getCameraToViewportRay(scrx, scry);
		Ogre::Vector3 vect = ray.getPoint(Camera.getNearClipDistance());
		
		ToX = vect.x;
		Toy = vect.y;
	}
}

GameFramework::GameFramework(boost::filesystem::path const &WorkPath, Ogre::SceneManager &SceneManager)
: m_SceneManager(SceneManager), m_TerrainMatManager(WorkPath), m_UnitEntityManager(WorkPath, m_SceneManager)
{
	vpWidth = m_SceneManager.getCamera("MainCam")->getViewport()->getActualWidth();
	vpHeight = m_SceneManager.getCamera("MainCam")->getViewport()->getActualHeight();
	// Open map
	std::ifstream map_txt("map.txt");
	// Create map
	m_pMap = he::Map::create_map(map_txt);
	// Create map renderer
	m_pMapRenderer.reset(new he::MapRenderer(m_pMap.get(), m_TerrainMatManager, m_SceneManager));
	// Create map model
	m_pMapRenderer->create_map_model();
	// Add some testing entities
//	m_AllUnits.push_back(m_UnitEntityManager.create_afv("germany", "sdkfz265", m_pMap->get_tile(2, 4)));

	// Associate to physics
	m_Physics.associate(m_pMapRenderer.get());

	// Use identity view/projection matrices
//	manual->setUseIdentityProjection(true);
//	manual->setUseIdentityView(true);

	float a_x = 5, a_z = 80, a_y = 0;
	float width = 1.3f * 40.f, height = 40.f;
//	convertScreenMetrics(512, 512, x, y, *m_SceneManager.getCamera("MainCam"));
//	manual->setRenderQueueGroup(Ogre::RENDER_QUEUE_7);

	
	{
		float x= a_x + 1, y = a_y, z = a_z;
		Ogre::ManualObject* manual = m_SceneManager.createManualObject("house_s");
		manual->setRenderQueueGroup(Ogre::RENDER_QUEUE_MAIN);
		manual->begin("house_s", Ogre::RenderOperation::OT_TRIANGLE_LIST);

		manual->position(x, y, z);
		manual->textureCoord(0.0f, 1.0f);
		manual->textureCoord(0.0f, 1.0f);

		manual->position(x + width, y, z);
		manual->textureCoord(1.0f, 1.0f);
		manual->textureCoord(1.0f, 1.0f);

		manual->position(x + width, y + height, z);
		manual->textureCoord(1.0f, 0.0f);
		manual->textureCoord(1.0f, 0.0f);

		manual->position(x, y + height, z);
		manual->textureCoord(0.0f, 0.0f);
		manual->textureCoord(0.0f, 0.0f);

		manual->triangle(0, 1, 2);
		manual->triangle(0, 2, 3);

		manual->end();

		m_SceneManager.getRootSceneNode()->createChildSceneNode()->attachObject(manual);
	}
	{
		float x= a_x, y = a_y, z = a_z;
		Ogre::ManualObject* manual = m_SceneManager.createManualObject("house");
		manual->setRenderQueueGroup(Ogre::RENDER_QUEUE_6);
		manual->begin("house", Ogre::RenderOperation::OT_TRIANGLE_LIST);

		manual->position(x, y, z);
		manual->textureCoord(0.0f, 1.0f);
		manual->textureCoord(0.0f, 1.0f);

		manual->position(x + width, y, z);
		manual->textureCoord(1.0f, 1.0f);
		manual->textureCoord(1.0f, 1.0f);

		manual->position(x + width, y + height, z);
		manual->textureCoord(1.0f, 0.0f);
		manual->textureCoord(1.0f, 0.0f);

		manual->position(x, y + height, z);
		manual->textureCoord(0.0f, 0.0f);
		manual->textureCoord(0.0f, 0.0f);

		manual->triangle(0, 1, 2);
		manual->triangle(0, 2, 3);

		manual->end();

		m_SceneManager.getRootSceneNode()->createChildSceneNode()->attachObject(manual);
	}
//	m_pMapRenderer->partition_scene_node(0, 0)->attachObject(manual);
}

void GameFramework::update(float Time)
{
	// Update physics
	m_Physics.update(Time);
}
